<?php
/**
 * helper.php
 * In twig: {{ helper.model('catalog/product').getProduct(28).name }}
 * Others:  model('catalog/product')->getProduct(28)
 *
 * @copyright  2017 opencart.cn - All Rights Reserved
 * @link       http://www.guangdawangluo.com
 * @author     Edward Yang <yangjin@opencart.cn>
 * @created    2017-11-29 10:52
 * @modified   2017-11-29 10:52
 */

namespace Utils;

use Cart\Cart;
use Cart\Customer;

class Helper
{
    private static $helper;

    public static function getSingleton()
    {
        if (self::$helper instanceOf Helper) {
            return self::$helper;
        } else {
            return self::$helper = new Helper;
        }
    }
    public function __call($name, $arguments)
    {
        $name = snake_case($name);
        if (!function_exists($name)) {
            throw new \Exception("The function {$name} is not exist!");
        }
        return call_user_func($name, $arguments);
    }

    public function sub_string($string, $length, $dot = '...')
    {
        return sub_string($string, $length, $dot);
    }

    public function config($key, $default = null)
    {
        return config($key, $default);
    }

    public function format_date($format, $timestamp = null)
    {
        return format_date($format, $timestamp);
    }

    public function image_resize($image = 'placeholder.png', $width = 100, $height = 100)
    {
        $image = $image?: 'placeholder.png'; // fix $image = '';
        return image_resize($image, $width, $height);
    }


    public function old($key, $default = null)
    {
        return old($key, $default);
    }

    public function model($route)
    {
        return model($route);
    }

    public function template($route)
    {
        if (config('config_theme') == 'default') {
            if (is_file(DIR_TEMPLATE . config('theme_default_directory') . "/template/{$route}.twig")) {
                return config('theme_default_directory') . "/template/{$route}.twig";
            }
        }

        if (is_file(DIR_TEMPLATE . config('config_theme') . "/template/{$route}.twig")) {
            return config('config_theme') . "/template/{$route}.twig";
        }
        return "default/template/{$route}.twig";
    }

    /**
     * @example in twig {{ helper.inWishList(product.product_id) ? "icon-active" : "" }}
     * @param int $product_id
     *
     * @return bool
     * @throws \Exception
     */
    public function inWishList($product_id)
    {
        if (! $product_id) return false;

        static $wish_prod_ids;
        if (is_null($wish_prod_ids)) { // static cache current session $wish_prod_ids
            /** @var Customer $customer */
            $customer = registry()->get('customer');
            if ($customer->isLogged()) { // merge customer db wish list product ids
                /** @var \ModelAccountWishlist $wishListModel */
                $wishListModel = model('account/wishlist');
                $wish_lists = $wishListModel->getWishlist();
                if (count($wish_lists)) {
                    $wish_prod_ids = array_column($wish_lists, 'product_id');
                } else {
                    $wish_prod_ids = [];
                }
            } elseif (isset(session()->data['wishlist'])) { // merge session wish list product ids
                $wish_prod_ids = session()->data['wishlist'];
            } else {
                $wish_prod_ids = [];
            }
        }

        return in_array($product_id, $wish_prod_ids);
    }

    /**
     * @example in twig {{ helper.inCompareList(product.product_id) ? "icon-active" : "" }}
     * @param int $product_id
     *
     * @return bool
     * @throws \Exception
     */
    public function inCompareList($product_id)
    {
        if (! $product_id) return false;

        static $compare_prod_ids;
        if (is_null($compare_prod_ids)) {
            if (isset(session()->data['compare'])) {
                $compare_prod_ids = array_values(session()->data['compare']);
            } else {
                $compare_prod_ids = [];
            }
        }

        return in_array($product_id, $compare_prod_ids);
    }

    public function wishCounts()
    {
        /** @var Customer $customer */
        $customer = registry()->get('customer');
        static $wish_counts;
        if (! is_null($wish_counts)) {
            return $wish_counts;
        }

        if ($customer->isLogged()) { // merge customer db wish list product ids
            /** @var \ModelAccountWishlist $wishListModel */
            $wishListModel = model('account/wishlist');
            $wish_counts = $wishListModel->getTotalWishlist();
        } elseif (isset(session()->data['wishlist'])) { // merge session wish list product ids
            $wish_counts = count(session()->data['wishlist']);
        } else {
            $wish_counts = 0;
        }

        return $wish_counts;
    }

    /**
     * @return int
     *
     * @throws \Exception
     */
    public function cartCounts()
    {
        static $cart_counts;
        if (isset($cart_counts)) {
            return $cart_counts;
        }

        /**
         * @var Cart $cart
         * @see dw-oc/catalog/controller/startup/startup.php:192
         */
        $cart = registry()->get('cart');
        $cart_counts = $cart->queryCart()->num_rows;

        return $cart_counts;
    }

    /**
     * @return int
     *
     * @throws \Exception
     */
    public function compareCounts()
    {
        return isset(session()->data['compare'])
            ? count(session()->data['compare'])
            : 0;
    }

    /**
     * @return int
     *
     * @throws \Exception
     */
    public function customerJwtToken()
    {
        static $token;
        if ($token) {
            return $token;
        }

        /** @var Customer $customer */
        $customer = registry()->get('customer');
        if (! $customer->isLogged()) {
            return null;
        }

        $customer_id = $customer->getId();
        $json = file_get_contents(HTTP_SERVER . "/api/v1/app/common/customer/$customer_id/regenerate-jwt-token");
        $data = json_decode($json, true);
        if (is_array($data) && $data['code'] === 0) {
            return $token = $customer->getJwtToken();
        } else {
            return null;
        }
    }

    public function session($key, $flush = false)
    {
        $session = registry()->get('session');

        $val = isset($session->data[$key]) ? $session->data[$key] : null;
        if ($val && $flush) {
            unset($session->data[$key]);
        }

        return $val;
    }

    public function sessionPull($key)
    {
        return $this->session($key, true);
    }

    /**
     * 名字不能是 isUrl 否则 twig 里面写 helper.url 会调用这个方法
     * @param $url
     *
     * @return bool
     */
    public function isHttpUrl($url)
    {
        return strpos($url, 'http') === 0;
    }

    /**
     * @example {{ helper.hasTryonModel(product_id) }}
     * @param $product_id
     *
     * @return bool
     * @throws \Exception
     */
    public function hasTryonModel($product_id)
    {
        if (! $product_id) return false;

        static $has_model_product_ids;
        if (! isset($has_model_product_ids)) {
            /** @var \ModelCatalogTryonModel $tryonModel */
            $tryonModel = model('catalog/tryon_model');
            $has_model_product_ids = $tryonModel->allPcProductIds();
        }

        return in_array($product_id, $has_model_product_ids);
    }


    public function const($name)
    {
        return defined($name) ? constant($name) : null;
    }

    /**
     * 判断字符串是否是网页支持的合法视频格式MP4，ogg，webm
     * @param $url
     * @return bool
     */
    public function isVideo($url) {
        $validate_mp4 = explode('.mp4',$url);
        $validate_ogg = explode('.ogg',$url);
        $validate_webm = explode('.webm',$url);

        return count($validate_mp4) > 1 || count($validate_ogg) > 1 || count($validate_webm) > 1;
    }
}
